package com.weijian.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.weijian.dal.model.NotificationMessage;
import com.weijian.mapper.NotificationMessageMapper;
import com.weijian.service.NotificationService;
import jakarta.annotation.Resource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 消息通知服务实现类
 */
@Service
public class NotificationServiceImpl extends ServiceImpl<NotificationMessageMapper, NotificationMessage>
        implements NotificationService {

    @Resource
    private NotificationMessageMapper notificationMessageMapper;

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    private static final String NOTIFICATION_CACHE_PREFIX = "notification:";
    private static final String UNREAD_COUNT_KEY = "notification:count:";
    private static final String MESSAGE_LIST_KEY = "notification:list:";

    @Override
    @Transactional
    public void sendNotification(NotificationMessage message) {
        // 1. 保存到数据库
        message.setIsRead(false);
        notificationMessageMapper.insert(message);

        // 2. 清除相关缓存
        clearUserCache(message.getReceiverId());
    }

    @Override
    public IPage<NotificationMessage> getUserMessages(Long userId, int page, int size) {
        String cacheKey = MESSAGE_LIST_KEY + userId + ":" + page + ":" + size;

        // 尝试从缓存获取
        IPage<NotificationMessage> cached = (IPage<NotificationMessage>) redisTemplate.opsForValue().get(cacheKey);
        if (cached != null) {
            return cached;
        }

        // 从数据库查询
        Page<NotificationMessage> pageParam = new Page<>(page, size);
        IPage<NotificationMessage> messages = notificationMessageMapper.getUserMessages(pageParam, userId);

        // 缓存5分钟
        redisTemplate.opsForValue().set(cacheKey, messages, 5, TimeUnit.MINUTES);

        return messages;
    }

    @Override
    public int getUnreadCount(Long userId) {
        String cacheKey = UNREAD_COUNT_KEY + userId;

        // 尝试从缓存获取
        Integer cached = (Integer) redisTemplate.opsForValue().get(cacheKey);
        if (cached != null) {
            return cached;
        }

        // 从数据库查询
        int count = notificationMessageMapper.getUnreadCount(userId);

        // 缓存10分钟
        redisTemplate.opsForValue().set(cacheKey, count, 10, TimeUnit.MINUTES);

        return count;
    }

    @Override
    public List<java.util.Map<String, Object>> getUnreadCountByType(Long userId) {
        return notificationMessageMapper.getUnreadCountByType(userId);
    }

    @Override
    @Transactional
    public boolean markAsRead(Long userId, Long messageId) {
        NotificationMessage message = notificationMessageMapper.selectById(messageId);
        if (message == null || !message.getReceiverId().equals(userId)) {
            return false;
        }

        message.setIsRead(true);
        message.setReadTime(LocalDateTime.now());
        notificationMessageMapper.updateById(message);

        // 清除缓存
        clearUserCache(userId);
        return true;
    }

    @Override
    @Transactional
    public boolean batchMarkAsRead(Long userId, List<Long> messageIds) {
        if (messageIds == null || messageIds.isEmpty()) {
            return false;
        }
        for (Long messageId : messageIds) {
            markAsRead(userId, messageId);
        }

        // 清除缓存
        clearUserCache(userId);
        return true;
    }

    @Override
    @Transactional
    public boolean deleteMessage(Long userId, Long messageId) {
        NotificationMessage message = notificationMessageMapper.selectById(messageId);
        if (message == null || !message.getReceiverId().equals(userId)) {
            return false;
        }

        // 软删除
        removeById(messageId);

        // 清除缓存
        clearUserCache(userId);
        return true;
    }

    /**
     * 清除用户相关的缓存
     */
    private void clearUserCache(Long userId) {
        // 清除未读计数缓存
        redisTemplate.delete(UNREAD_COUNT_KEY + userId);

        // 清除消息列表缓存（模糊删除）
        String pattern = MESSAGE_LIST_KEY + userId + ":*";
        redisTemplate.delete(redisTemplate.keys(pattern));
    }
}